package com.squirrel.serialportcore.machine.consumer;


import com.rabbitmq.client.Channel;
import com.squirrel.serialportcore.common.CommonBase;
import com.squirrel.serialportcore.common.ContentBase;
import com.squirrel.serialportcore.exception.CoreException;
import gnu.io.SerialPort;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.OutputStream;

/**
 * 消息消费者
 * 将消息命令解析发送到串口
 *
 * @author Squbi
 * @date 2021/3/23 9:37
 */
@Service
public class QueueConsumer implements ChannelAwareMessageListener {
    private static final Logger logger = LoggerFactory.getLogger(QueueConsumer.class);

    @Override
    public void onMessage(Message message, Channel channel) {
        if (!CommonBase.isTotalInit()) {
            return;
        }
        MessageProperties properties = message.getMessageProperties();
        logger.info(" |-> 收到消息 {} 是否为重投消息 {}", message.getBody(), properties.getRedelivered());
        logger.debug(" -debug- 消息详情 {} 信道 {}", message, channel);
        String receivedRoutingKey = properties.getReceivedRoutingKey();
        String portName = receivedRoutingKey.substring(receivedRoutingKey.lastIndexOf(".") + 1);
        if ("".equals(portName)) {
            String receivedExchange = properties.getReceivedExchange();
            portName = receivedExchange.substring(receivedExchange.lastIndexOf(".") + 1);
        }
        byte[] order = message.getBody();
        //获取串口对象
        SerialPort serialPort = ContentBase.getSerialPortMap().get(portName);
        if (serialPort == null) {
            logger.error(" 接受错误通道命令 串口 {}", portName);
            return;
        }
        OutputStream outputStream = null;
        try {
            outputStream = serialPort.getOutputStream();
            outputStream.write(order);
            outputStream.flush();
            logger.info(" |--> 串口 {} 已发送命令 x16-> {}", portName, order);
            //回复akc multiple为是否一次ack多条消息
            channel.basicAck(properties.getDeliveryTag(), false);
        } catch (Exception e) {
            throw new CoreException(logger, e, " 串口名 {} 命令传送异常 {}", portName, e.getMessage());
        } finally {
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
